# 4. 其他流程控制工具

## 4.1 if

## 4.2.  For

## 4.3. range() 函数

for i in  range(5):             # 遍历一个数字序列
    print(i, end=',')
print(i)

## 4.4. break 和 continue 语句, 以及循环中的 else 子句

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            break
    else:
        # loop fell through without finding a factor
        print(n, 'is a prime number')


for num in range(2, 10):
    if num % 2 == 0:
        print("Found an even number", num)
        continue
    print("Found an odd number", num)

## 4.5. pass 语句
'''什么也不做
'''

## 4.6. 定义函数
print('--------------- def 定义函数')
def fib(str: n):
    """函数说明文档 doc"""
    print(n)
print(fib.__doc__)              # 函数文档
print(fib(0))                   # 不带 return , 函数默认返回值: None

def fib2(n):
    """ Return a list  containing the Fibonacci series up to n."""
    resutl = []
    a, b = 0, 1
    while a < n:
        resutl.append(a) # see below
        a, b = b, a + b
    return resutl               # return 语句, 从函数内部返回一个值

print(fib2(100))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

## 4.7. 函数定义的更多形式

### 4.7.1. 参数默认值

def ask_ok(prompt, retries = 4, reminder = 'Please try again!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise ValueError('invalid use response')
        print(reminder)

# ask_ok('Do you really want to quit?')
# ask_ok('OK to overwrite the file?', 2)
# ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

i = 5
def f(arg = i):
    print(arg)

i = 6
f()                # 重要警告： 默认值只会执行一次。  打印: 5
'''默认值为可变对象的情况 ,
存储在后续调用中传递给它的参数
'''
def f(a, L = []):
    L.append(a)
    return L
print(f(1))         # [1]
print(f(2))         # [1, 2]
print(f(3))         # [1, 2, 3]

'''不共享
'''
def f2(a, L = None):
    if L is None:
        L = []
    L.append(a)
    return L

print(f2(1))                # [1]
print(f2(2))                # [2]

### 4.7.2. 关键字参数
'''关键字形参也被称为命名形参
'''
def parrot(voltage, state = 'a stiff', action = 'voom', type = 'Norwegian Blue'):               # 一个必选参数, 三个可选参数
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

'''关键字参数必须跟随在位置参数的后面
'''
parrot('a million', 'bereft of life', 'jump')

''' **name 参数 , 接收一个字典
'''
print("-" * 40)
def cheese_shop(kind, *arguments, **keywords):
    print(kind)
    for arg in arguments:
        print("arg> " + arg)
    print("-" * 40)
    for key in keywords:
        print(key, " : ", keywords[key])

'''注意打印时关键字参数的顺序保证与调用函数时提供它们的顺序是相匹配的。
'''
cheese_shop("kind", "kind2", "kind3", shopkeeper='Michael Palin', client='Johon Chess', sketch='Cheese Shop Sketch')

### 4.7.3. 特殊参数
'''符号: /  和 *
'''

#### 4.7.3.1. 位置或关键字参数

#### 4.7.3.2. 仅限位置参数

#### 4.7.3.3. 仅限关键字参数

#### 4.7.3.4. 函数示例

#### 4.7.3.5. 概括

### 4.7.4. 任意的参数列表
'''
最不常用
'''

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))
    file.flush()
    file.close()

# file_1 = open('./args.txt', mode='x')
# write_multiple_items(file_1, "/", "a", "b", "c")

                #
def concat(*args, sep = '/'):
    return sep.join(args)

print(concat('12','323', 'dsf'))

### 4.7.5. 解包参数列表
'''当参数已经在列表或元组中但要为需要单独位置参数的函数调用解包时
  * 和 ** 操作符的使用
'''
list(range(3, 6))
#list(range(*args))

def parrot2(voltage, state='a stiff', action='voom'):
    print(voltage, state, action)

parrot2(**{"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"})

### 4.7.6. Lambda 表达式
'''可以用 lambda 关键字来创建一个小的匿名函数
'''

def make_incrementor(n):
    """增量器"""
    return lambda x:x + n               # 使用一个lambda表达式来返回一个函数

f = make_incrementor(5)
print(f(20))

pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
pairs.sort(key=lambda pair: pair[1])            # 传递一个小函数作为参数:
print(pairs)

### 4.7.7. 文档字符串

def my_function():                      # 就是一些内容和格式的约定
    """Do nothing, but document it.

    No, really, it doesn't do anything.
    """
    pass

print(my_function.__doc__)

### 4.7.8. 函数标注

def f(ham: str, eggs: str = 'eggs') -> str:
    print("Annotations: ", f.__annotations__)
    print("Arguments:", ham, eggs)
    return ham + ' and ' + eggs

fr = f('spam')
print(fr)

## 4.8 编码风格

''' PEP 8
   https://www.python.org/dev/peps/pep-0008/
'''


